home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_13_10
/
mashlan
/
checkptr.h
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-15
|
8KB
|
279 lines
// checkptr.h listing 1
// copyright 1995 Robert Mashlan
// class templates for CheckedPtr and CheckedClassPtr
#ifndef __CHECKPTR_H
#define __CHECKPTR_H
#include <stddef.h>
#include <except.h>
#include <cstring.h>
class xCheckedPtr : public xmsg
{
public:
xCheckedPtr( const string& why ) : xmsg(why) {}
};
class xnullptr : public xCheckedPtr {
public:
xnullptr() : xCheckedPtr("dereferenced null pointer") {}
void raise()
{ throw *this; }
};
class xoutofrange : public xCheckedPtr {
public:
xoutofrange() : xCheckedPtr("pointer out of range") {}
void raise()
{ throw *this; }
};
class xnotsamebase : public xCheckedPtr {
public:
xnotsamebase()
: xCheckedPtr("comparison between two pointers not of the same base")
{}
void raise()
{ throw *this; }
};
template<class T>
class CheckedPtr {
public:
// default constructor
CheckedPtr(T *p = 0, size_t limit=1, T* base = 0 )
: p(p), base(base?base:p), limit(limit)
{
if(p>this->base+limit||p<this->base)
xoutofrange().raise();
}
// copy constructor
CheckedPtr( const CheckedPtr<T>& orig )
: p(orig.p), base(orig.base), limit(orig.limit)
{}
// access to base and limit
void SetBaseAndLimit( T* base, size_t limit )
{
if(!base)
base = p;
if(!limit)
limit = 1;
this->base=base;
this->limit=limit;
if( p && (p<base || base+limit<p) )
xoutofrange().raise();
}
// conversion operator
operator T*() const
{ return p; }
// reference operators
T& operator*() const
{ return operator[](0); }
T& operator[]( ptrdiff_t i ) const
{
if(!p) // null pointer?
xnullptr().raise();
// check for out of range reference
if( p+i<base || base+limit <= p+i )
xoutofrange().raise();
return p[i];
}
// assignment operators
CheckedPtr<T>& operator=( const CheckedPtr<T>& cp )
{ p = cp.p; base=cp.base; limit=cp.limit; return *this; }
CheckedPtr<T>& operator=( T* p )
{ this->p = base = p; limit = 1; return *this; }
CheckedPtr<T>& operator+=( ptrdiff_t n )
{
if(!p)
xnullptr().raise();
if( p+n < base || base + limit < p+n )
xoutofrange().raise();
p += n;
return *this;
}
CheckedPtr<T>& operator-=( ptrdiff_t n )
{ return operator+=(-n); }
// additive operators
CheckedPtr<T> operator+( ptrdiff_t n ) const
{ return CheckedPtr<T>(*this).operator+=(n); }
CheckedPtr<T> operator-( ptrdiff_t n ) const
{ return CheckedPtr<T>(*this).operator-=(n); }
ptrdiff_t operator-( const CheckedPtr<T>& cp ) const
{
if(base!=cp.base)
xnotsamebase().raise();
return p-cp.p;
}
ptrdiff_t operator-( CheckedPtr<T>& cp ) const
{ return operator-((const CheckedPtr<T>)cp); }
ptrdiff_t operator-( T *p ) const
{
if( p<base || base+limit<p )
xnotsamebase().raise();
return this->p-p;
}
friend ptrdiff_t operator-( T* p, CheckedPtr<T>& cp );
// increment and decrement
CheckedPtr<T>& operator++(int)
{ return operator+=(1); }
CheckedPtr<T> operator++()
{
CheckedPtr<T> r(*this);
operator++(0);
return r;
}
CheckedPtr<T>& operator--(int)
{ return operator-=(1); }
CheckedPtr<T> operator--()
{
CheckedPtr<T> r(*this);
operator--(0);
return r;
}
// logical negation
bool operator!() const
{ return !p; }
// equality operators
bool operator==( const CheckedPtr<T>& cp ) const
{ return p == cp.p; }
bool operator==( T* p ) const
{ return this->p == p; }
bool operator != ( const CheckedPtr<T>& cp ) const
{ return p != cp.p; }
bool operator!=( T* p ) const
{ return this->p != p; }
// relational operators
bool operator<( const CheckedPtr<T>& cp ) const
{ return operator-(cp) < 0; }
bool operator<( T* p ) const
{ return operator-(p) < 0; }
bool operator<=( const CheckedPtr<T>& cp ) const
{ return operator-(cp) <= 0; }
bool operator<=( T* p ) const
{ return operator-(p) <= 0; }
bool operator>( const CheckedPtr<T>& cp ) const
{ return operator-(cp) > 0; }
bool operator>( T* p ) const
{ return operator-(p) > 0; }
bool operator>=( const CheckedPtr<T>& cp ) const
{ return operator-(cp) >= 0; }
bool operator>=( T* p ) const
{ return operator-(p) >= 0; }
protected:
T* p; // pointer that this class represents
T* base; // base of the array that p is a member of
size_t limit; // number of elements in the array,
// 1 for non-array pointers
};
template<class T> inline
ptrdiff_t operator-( T* p, CheckedPtr<T>& cp )
{
if( p < cp.base || cp.base+cp.limit < p )
xnotsamebase().raise();
return p-cp.p;
}
template<class T> inline
CheckedPtr<T> operator+( ptrdiff_t n, const CheckedPtr<T>& cp )
{
return cp.operator+(n);
}
// non-member equality operators
template<class T> inline
bool operator==( T* p, const CheckedPtr<T>& cp )
{
return cp.operator==(p);
}
template<class T> inline
bool operator!=( T* p, const CheckedPtr<T>& cp )
{
return cp.operator!=(p);
}
// non-member relational operators
template<class T> inline
bool operator<( T* p, const CheckedPtr<T>& cp )
{
return cp.operator>=(p);
}
template<class T> inline
bool operator<=( T* p, const CheckedPtr<T>& cp )
{
return cp.operator>(p);
}
template<class T> inline
bool operator>( T* p, const CheckedPtr<T>& cp )
{
return cp.operator<=(p);
}
template<class T> inline
bool operator>=( T* p, const CheckedPtr<T>& cp )
{
return cp.operator<(p);
}
template<class T>
class CheckedClassPtr : public CheckedPtr<T> {
public:
CheckedClassPtr(T *p=0, size_t limit=1, T* base=0 )
: CheckedPtr<T>(p,limit,base)
{}
CheckedClassPtr( const CheckedClassPtr<T>& orig )
: CheckedPtr<T>(orig)
{}
// class memory access operator
T* operator->() const { return &operator*(); }
// assignment operators
CheckedClassPtr<T>& operator=( const CheckedClassPtr<T>& cp )
{ CheckedPtr<T>::operator=(cp); return *this; }
CheckedClassPtr<T>& operator+=( ptrdiff_t n )
{ CheckedPtr<T>::operator+=(n); return *this; }
CheckedClassPtr<T>& operator-=( ptrdiff_t n )
{ CheckedPtr<T>::operator-=(n); return *this; }
// additive operators
CheckedClassPtr<T> operator+( ptrdiff_t n ) const
{ return CheckedClassPtr<T>(*this).operator+=(n); }
CheckedClassPtr<T> operator-( ptrdiff_t n ) const
{ return CheckedClassPtr<T>(*this).operator-=(n); }
// increment and decrement
CheckedClassPtr<T>& operator++(int)
{ return operator+=(1); }
CheckedClassPtr<T> operator++()
{ CheckedClassPtr<T> r(*this); operator++(0); return r; }
CheckedClassPtr<T>& operator--(int)
{ operator-=(1); return *this; }
CheckedClassPtr<T> operator--()
{ CheckedClassPtr<T> r(*this); operator--(0); return r; }
};
template<class T> inline
CheckedClassPtr<T> operator + ( ptrdiff_t n, const CheckedClassPtr<T>& p )
{
return p.operator+(n);
}
#endif